/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package mb.mbpart.async;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.concurrent.BlockingQueue;
import mb.config.Constants;
import mb.config.DatabaseConfig;
import mb.mbmiddle.MbPartMiddle;
import mb.mbpart.memory.BaseMemory;
import mb.mbpart.object.NewsObject;
import mb.utils.LogText;

/**
 *
 * @author thanh.nguyenchi
 */
public class AsyncThread extends Thread {
    LogText objLog;
    boolean isKeepRunning;
    BlockingQueue<AysncObject> queue;
    DatabaseConfig objConfig;
    private Connection conn = null; 
    MbPartMiddle objMain;
    
    public AsyncThread(BlockingQueue<AysncObject> queue,LogText objLog, DatabaseConfig objConfig,MbPartMiddle objMain) throws Exception {        
        this.setName(Constants.STR_ASYNC_THREAD);
        this.queue = queue;
        this.objLog = objLog; 
        this.objConfig = objConfig;
        this.objMain = objMain;
        
        initConnection();
    }
    
    private void initConnection(){
        try{
            // the sql server driver string
            Class.forName("net.sourceforge.jtds.jdbc.Driver");            

            // get the sql server database connection
            conn = DriverManager.getConnection(objConfig.getUrl(),objConfig.getUser(),objConfig.getPass());
            if (conn != null){
                this.isKeepRunning = true;
                log("Update thread is starting....");
            }
            else{                
                this.isKeepRunning = false;
            }
        }
        catch(SQLException ex){
            log("[AsyncThread] initConnection err=" + ex.toString());
        }
        catch(Exception ex) { 
            log("[AsyncThread] initConnection err=" + ex.toString());
        } 
    }
    
    private void closeConnection(){
        if (conn != null){
            try{
                conn.close();
            }
            catch(Exception ex){
                
            }            
        }
    }
    
    public void log(String sLog){
        objLog.log(sLog);
    }
    
    public void closeThread(){
        objLog.closeLog();
        closeConnection();
    }
    
    public void stopUpdate(){
        try{
            isKeepRunning = false;
            closeThread();
            Thread.currentThread().sleep(3000);
        }
        catch(Exception ex){
            
        }
    }
    
    
    public void run(){
        
        //get the msg and update to global memory
        while(isKeepRunning){
            try{
                AysncObject objAsync = (AysncObject)queue.take();
                if (objAsync != null){
                    handlerMsg(objAsync);
                }
            }
            catch(Exception ex){
               closeThread();
            }			
        }
    }
    
    public void handlerMsg(AysncObject obj){
        log("[ClassName] : " + obj.getType() + " id : " + obj.getId());
        switch(obj.getType()){
            case Constants.INT_SERVICE_TYPE:
                A1(obj.getId());
                break;
            case Constants.INT_NEWS_TYPE:
                A2(obj.getId());
                break;
            default: 
                break;
        }
    }
    
    private void A1(long id){
        String sService = getNewsbyId(id);
        // add to services memory
        BaseMemory objMemory = new BaseMemory(sService);
        String key = Constants.STR_MEM_SERVIES + Constants.STR_ID_CODE + id;
        objMain.objMemory.put(key,objMemory);
    }
    
    private void A2(long id){
        getNewsWithPage(id);
    }
    
    public void addNews2Mem(long id,int page,String data){
        BaseMemory objMemory = new BaseMemory(data);
        String key = Constants.STR_MEM_NEWS + Constants.STR_ID_CODE + id + Constants.STR_PAGE_CODE + page;
        objMain.objMemory.put(key,objMemory);
    }
    
    public void addNewsTotal2Mem(long id,int total){
        BaseMemory objMemory = new BaseMemory(String.valueOf(total));
        String key = Constants.STR_MEM_NEWS + Constants.STR_ID_CODE + id + Constants.STR_TOTAL_ROW;
        objMain.objMemory.put(key,objMemory);
    }
    
    private void getNewsWithPage(long id){
        Statement stmt = null;
            
        String query =  "DECLARE	@return_value int \n" +
                        "EXEC	@return_value = [sploadNewsById] \n" +
                        "       @Cate_id = " + id + " \n" +
                        "       SELECT	'Return Value' = @return_value";
        
        String sResult = "[";  
        
        try {     
            stmt = conn.createStatement();
            ResultSet rs = stmt.executeQuery(query);
            int items = 0;
            int page = 1;
            int total = 0;
            while (rs.next()) {
                total ++;
                items ++;
                NewsObject obj = new NewsObject();
                obj.C_NEWS_ID = rs.getInt(1);
                obj.C_TITLE = rs.getString(2);
                obj.C_TEASER = rs.getString(3);
                obj.C_CONTENT = rs.getString(4);
                obj.C_AVATAR = rs.getString(5);
                obj.C_ADDRESS = rs.getString(6);
                obj.C_LATITUDE = rs.getDouble(7);
                obj.C_LONGITUDE = rs.getDouble(8);
                obj.C_FROM_DATE = rs.getDate(9).toString();
                obj.C_TO_DATE = rs.getDate(10).toString();
                obj.C_PHONE = rs.getString(11);
                obj.C_LINK = rs.getString(12);
                obj.C_TYPE = id; 
                
                sResult = sResult + obj.toJson(id,objConfig) + ",";
                
                if (items >= objConfig.getPageLimit()){
                    if (sResult.endsWith(",")){
                        sResult = sResult.substring(0, sResult.length() - 1);
                    }
                    
                    sResult = sResult + "]";
                    //add to memory
                    addNews2Mem(id,page,sResult);
                    
                    //reset
                    page++;
                    items = 0;
                    sResult = "[";
                }
            }
            
            if (sResult.endsWith(",")){
                sResult = sResult.substring(0, sResult.length() - 1);
            }
            
            sResult = sResult + "]";
            
            // add to memory
            addNews2Mem(id,page,sResult);
            
            // add totalRows to memory
            addNewsTotal2Mem(id,total);
            
            rs.close();
            stmt.close();
        } catch (Exception ex ) {
            return;
        } 
        
        return;
    }
    private String getNewsbyId(long id){
        Statement stmt = null;
            
        String query =  "DECLARE	@return_value int \n" +
                        "EXEC	@return_value = [sploadNewsById] \n" +
                        "       @Cate_id = " + id + " \n" +
                        "       SELECT	'Return Value' = @return_value";
        
        String sResult = "[";  
        
        try {     
            stmt = conn.createStatement();
            ResultSet rs = stmt.executeQuery(query);            
            while (rs.next()) {
                NewsObject obj = new NewsObject();
                obj.C_NEWS_ID = rs.getInt(1);
                obj.C_TITLE = rs.getString(2);
                obj.C_TEASER = rs.getString(3);
                obj.C_CONTENT = rs.getString(4);
                obj.C_AVATAR = rs.getString(5);
                obj.C_ADDRESS = rs.getString(6);
                obj.C_LATITUDE = rs.getDouble(7);
                obj.C_LONGITUDE = rs.getDouble(8);
                obj.C_FROM_DATE = rs.getDate(9).toString();
                obj.C_TO_DATE = rs.getDate(10).toString();
                obj.C_PHONE = rs.getString(11);
                obj.C_LINK = rs.getString(12);
                obj.C_TYPE = id; 
                
                sResult = sResult + obj.toJson(id,objConfig) + ",";
            }
            
            if (sResult.endsWith(",")){
                sResult = sResult.substring(0, sResult.length() - 1);
            }
            
            sResult = sResult + "]";
            
            rs.close();
            stmt.close();
        } catch (Exception ex ) {
            return "[]";
        } 
        
        return sResult;
    }
    
    
}
